package com.chezai.client.global.device;


import android.app.Activity;
import android.app.StatusBarManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.TextUtils;
import android.widget.Toast;

import com.chezai.client.bean.ReadIdCardBean;
import com.chezai.client.global.TerminalApplication;
import com.chezai.client.utils.CameraMgr;
import com.chezai.client.utils.CoreConfig;
import com.chezai.client.utils.DateUtil;
import com.chezai.client.utils.DeviceUtils;
import com.chezai.client.utils.FileUtil;
import com.chezai.client.utils.ToastUtil;
import com.lyt.pwr.PowerManager;
import com.lyt.rfid_demo.Native;
import com.orhanobut.logger.Logger;

import org.greenrobot.eventbus.EventBus;

/**
 * Describe 立宇泰 501B
 * Created by LZF on 2016/12/5.
 */
public class C501Hardware extends DifferenceHardware {
    private static final int card_A = 0x02;
    private static final int card_B = 0x01;
    private final int FM1702_NOTAGERR = -1; // 无卡
    private final int FM1702_CRCERR = -2; // 卡片CRC校验错误
    private final int FM1702_EMPTY = -3;// 数值溢出错误
    private final int FM1702_AUTHERR = -4;// 验证不成功
    private final int FM1702_PARITYERR = -5; // 卡片奇偶校验错误
    private final int FM1702_CODEERR = -6; // 通讯错误(BCC校验错)
    private final int FM1702_SERNRERR = -8;// 卡片序列号错误(anti-collision 错误)
    private final int FM1702_SELECTERR = -9;// 卡片数据长度字节错误(SELECT错误)
    private final int FM1702_NOTAUTHERR = -10;// 卡片没有通过验证
    private final int FM1702_BITCOUNTERR = -11;// 从卡片接收到的位数错误
    private final int FM1702_BYTECOUNTERR = -12;// 从卡片接收到的字节数错误仅读函数有效
    private final int FM1702_RESTERR = -13; // 调用restore函数出错
    private final int FM1702_TRANSERR = -14; // 调用transfer函数出错


    // ******************* 函数错误代码定义********************
    private final int FM1702_INCRERR = -16; // 调用increment函数出错
    private final int FM1702_READERR = -18; // 调用read函数出错
    private final int FM1702_FRAMINGERR = -20; // FM1702帧错误
    private final int FM1702_INTIVALERR = -24; // 调用初始化函数出错
    private final int FM1702_CHIPERR = -43; // 芯片未加电或已损坏
    private final int TYPEERR = -44; // 初始化类型失败
    private boolean interrupt;
    private int noReadCardEvent;

    private synchronized static String bytesToHexString(byte[] src, int length) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    @Override
    public String getSerialNumber(Context context) {
        CoreConfig coreConfig = new CoreConfig();
        coreConfig.getCore();
        String serialNum1 = "";
        String serialNum = coreConfig.getCoreNum();
        if (!TextUtils.isEmpty(serialNum)) {
            if (serialNum.length() > 6) {
                int n = 7;
                serialNum1 = serialNum.substring(serialNum.length() - n, serialNum.length());
            }
        }
        return serialNum1;
    }

    @Override
    public String readIcCard(Context context) {
        String show = null;
        try {
            //fml模块是否已经打开
            try {
                Native.close_fm1702();
            } catch (Exception e) {
                e.printStackTrace();
            }
            boolean isOpen = Native.open_fm1702();
            if (isOpen) {
                int ret = Native.select_type(card_A);
                showError(context, ret);
                byte uid[] = Native.New_read_A();
                if (uid.length <= 3) {// 无卡错误不在读卡号时捕捉，因为与无卡相关的UI已经做好了。
                    int value = uid[0];
                    if (value * (-1) == FM1702_NOTAGERR) {
                        showError(context, FM1702_NOTAGERR);
                    } else {
                        value = value * (-1);
                    }
                }
                show = bytesToHexString(uid, uid.length);
                if (show != null && show.length() > 2) {
                    show = show.substring(0, show.length() - 2);
                }
                Native.close_fm1702();
            } else {
                ToastUtil.showToast(context, "读卡器模块打开失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Logger.t("C501Hardware readIcCard").i("run: " + show);
        return show;
    }

    @Override
    public void setCalibrateTime() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            try {
                ContentResolver cr = TerminalApplication.getTerminalContext().getContentResolver();
                if (!DeviceUtils.isDateTimeAuto(cr)) {
                    DeviceUtils.setAutoDateTime(cr);
                }
                if (!DeviceUtils.isTimeZoneAuto(cr)) {
                    DeviceUtils.setAutoTimeZone(cr);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void openSettings(Context context) {
        Intent intent = new Intent("/");
        ComponentName cm = new ComponentName("com.android.settings", "com.android.settings.Settings");
        intent.setComponent(cm);
        intent.setAction("android.intent.action.VIEW");
        context.startActivity(intent);
    }

    @Override
    public long getPowerTime() {
        long powerDowTime = 0;
        try {
            PowerManager mPowerManager = new PowerManager();
            String time = mPowerManager.getPowerDownTime();
            Logger.t("C501Hardware getPowerTime").i(mPowerManager.getPowerDownTime());
            Logger.t("C501Hardware getPowerTime").i("是否掉电开机: " + mPowerManager.isPowerDownUp());
            if (!TextUtils.isEmpty(time)) {
                powerDowTime = DateUtil.stringTimeToLong(time, DateUtil.sf3);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return powerDowTime;
    }

    @Override
    public boolean cameraIsCanUse() {
        return CameraMgr.cameraIsCanUsed();
    }

    @Override
    public boolean controlRelay(boolean open) {
        boolean state1 = com.lyt.gpio_demo.Native.setRelay(open);
        Logger.t("C501Hardware controlRelay").i("controlRelay: " + state1);
        return state1;
    }

    @Override
    public void installApk(final Context context, final String fileUrl) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String filePath = fileUrl.replace("file://", "");
                String command = "pm install -r -f " + filePath;
                FileUtil.execCommand(context, command, fileUrl);
            }
        }).start();

    }

    @Override
    public void setAccPowerTime(Context context, long powerTime) {
        long time = 0;
        try {
            time = Settings.System.getLong(context.getContentResolver(), "acc_off_timeout");
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        if (time < 3 * 60 * 1000) {
            try {
                Settings.System.putLong(context.getContentResolver(), "acc_off_timeout", powerTime);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void setScreenOrientation(Activity activity) {
        if (activity.getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
    }

    @Override
    public boolean isNeedRotaingImage() {
        return false;
    }

    @Override
    public void disableNotificationBar(Context context) {
        StatusBarManager mStatusBarManager = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
        mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
    }

    @Override
    public void rebootDevice(Context context) {

    }

    @Override
    public void closeSerialPort() {
        interrupt = false;
        try {
            Native.close_fm1702();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void readIDCard(Context context) {
        if (!Native.open_fm1702()) {
            Toast.makeText(context, "设备打开失败，请重试", Toast.LENGTH_SHORT).show();
            return;
        }
        showError(context, Native.select_type(card_B));
        interrupt = true;
        ReadIDCardThread thread = new ReadIDCardThread();
        thread.start();
    }

    private void showError(Context context, int err_id) {
        switch (err_id) {
            case FM1702_NOTAGERR:
                ToastUtil.showToast(context, "没有插入学时卡");
                break;
            case FM1702_CRCERR:
                ToastUtil.showToast(context, "卡片CRC校验错误");
                break;
            case FM1702_EMPTY:
                ToastUtil.showToast(context, "数值溢出错误");
                break;
            case FM1702_AUTHERR:
                ToastUtil.showToast(context, "验证不成功");
                break;
            case FM1702_CODEERR:
                ToastUtil.showToast(context, "卡片奇偶校验错误");
                break;
            case FM1702_PARITYERR:
                ToastUtil.showToast(context, "通讯错误(BCC校验错)");
                break;
            case FM1702_SERNRERR:
                ToastUtil.showToast(context, "卡片序列号错误(anti-collision 错误)");
                break;
            case FM1702_SELECTERR:
                ToastUtil.showToast(context, "卡片数据长度字节错误(SELECT错误)");
                break;
            case FM1702_NOTAUTHERR:
                ToastUtil.showToast(context, "卡片没有通过验证");
                break;
            case FM1702_BITCOUNTERR:
                ToastUtil.showToast(context, "从卡片接收到的位数错误");
                break;
            case FM1702_BYTECOUNTERR:
                ToastUtil.showToast(context, "从卡片接收到的字节数错误仅读函数有效");
                break;
            case FM1702_RESTERR:
                ToastUtil.showToast(context, "调用restore函数出错");
                break;
            case FM1702_TRANSERR:
                ToastUtil.showToast(context, "调用transfer函数出错");
                break;
            case FM1702_INCRERR:
                ToastUtil.showToast(context, "调用increment函数出错");
                break;
            case FM1702_READERR:
                ToastUtil.showToast(context, "调用read函数出错");
                break;
            case FM1702_FRAMINGERR:
                ToastUtil.showToast(context, "FM1702帧错误");
                break;
            case FM1702_INTIVALERR:
                ToastUtil.showToast(context, "调用初始化函数出错");
                break;
            case FM1702_CHIPERR:
                ToastUtil.showToast(context, "芯片未加电或已损坏");
                break;
            case TYPEERR:
                ToastUtil.showToast(context, "初始化类型失败");
                break;
            default:
                break;
        }
    }

    //学员身份证登录
    public class ReadIDCardThread extends Thread {
        boolean isFirst = true;
        private String uid = "";

        public void run() {
            do {
                SystemClock.sleep(1000);
                synchronized (Native.class) {
                    uid = Native.read_B();
                    if (uid.length() <= 3) {
                        if (noReadCardEvent % 10 == 0) {
                            EventBus.getDefault().post(new ReadIdCardBean(ReadIdCardBean.STATUS_ERROR, ""));
                        }
                        noReadCardEvent++;
                        continue;
                    }
                    if (isFirst) {
                        isFirst = false;
                        String idCard = uid.replaceAll("\\s*", "").substring(0, 16);
                        Logger.t(TAG).d("IDCard num:" + idCard);
                        EventBus.getDefault().post(new ReadIdCardBean(ReadIdCardBean.STATUS_SUCESS, idCard));
                    }
                    closeSerialPort();
                }
            } while (interrupt);
        }
    }

}
